﻿#define DOWN_PART //分包下载
#define AUTOFINISH //自动完成下载
#define YSPOS_MODE
#if YSPOS_MODE
    #define USE_DEFAULT_URL_WHEN_NULL  //当取不到URL时是否使用一个默认的连接地址
    #define CHECK_SERVICE //分析是否需要重启某些服务
    #define SILENT_MODE //此模式是YSPOS用的
#else
    #define FIXXED_PROG //报表模式
#endif
/*
 *DELAY_UPDATE
 *延迟更新模式(不杀死主程序,主程序下次启动时从临时目录直接复制要更新的文件)
 *此模式无法执行服务进程的停止重启，也无法执行文件的重命名操作
 *此开关不可与SILENT_MODE同时定义
 */
//#define DELAY_UPDATE
/*
 *SILENT_MODE
 *静默更新模式
 *更新时不显示更新程序界面,更新完之后提示用户1分钟之后将重启主程序，也可以让用户立即重启
 *最好是检查时间，如果整个更新花费N分钟以上才提醒用户,否则按一般模式执行
 *此开关不可与DELAY_UPDATE同时定义
 */
using System;
using System.Web;
using System.IO;
using System.Net;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace BIN
{
    class UpdateUrlSpeed
    {
        public string Url { get; set; }
        public int TestMSecond { get; set; }
        public bool IsDefault { get; set; }
        public UpdateUrlSpeed(string url)
            :this(url,100000,false)
        {
        }
        public UpdateUrlSpeed(string url, int mSecond)
        {
            this.Url = url;
            this.TestMSecond = mSecond;
        }
        public UpdateUrlSpeed(string url, int mSecond,bool isDefault):this(url,mSecond)
        {
            this.IsDefault = isDefault;
        }
    }
    public class AppUpdater:IDisposable
    {
        #region "Control Points"
        /// <summary>
        /// 固定的程序名称
        /// </summary>
        public static string FixxedProgName
        {
            get
            { 
#if FIXXED_PROG 
                return "YSRC.EXE";
#else
                return string.Empty;
#endif
            }
        }
        /// <summary>
        /// 是否有固定的程序名称
        /// </summary>
        public static bool HasFixxedSetting
        {
            get
            {
                return !string.IsNullOrEmpty(FixxedProgName);
            }
        }
        /// <summary>
        /// 同时也杀掉这个进程
        /// </summary>
        public static string AlsoKillProg
        {
            get { return "Parent.exe"; }
        }
        /// <summary>
        /// 提醒更新模式,不杀掉进程，等下次启动主进程后再覆盖文件
        /// </summary>
        public static bool RewakeUpdateMode
        {
            get
            {
#if DELAY_UPDATE
                return true;
#else
                return false;
#endif
            }
        }
        /// <summary>
        /// 静默模式的更新
        /// </summary>
        public static bool SilentMode
        {
            get
            { 
#if SILENT_MODE 
                return true;
#else
                return false;
#endif
            }
        }
        public static bool YsPosMode
        {
            get
            {
#if YSPOS_MODE
                return true;
#else
            return false;
#endif
            }
        }
        public static bool CheckOpService
        {
            get
            { 
#if CHECK_SERVICE
                return true;
#else
                return false;
#endif
            }
        }
        public static bool AutoFinish
        {
            get
            { 
#if AUTOFINISH 
                return true;
#else
                return false;
#endif
            }
        }
        public static bool PartialDowning
        {
            get
            {
#if DOWN_PART
                return true;
#else
            return false;
#endif
            }
        }
        public static readonly string DownloadTempDir =
            ShareMet.CombineDir(ShareMet.GetAppDir(), "temp");
        #endregion
        private string _svrFilePath="", _clientFilePath="";
        private string _updaterUrl;
        private bool disposed = false;
        /// <summary>
        /// 限制升级的KEY,匹配UserConfig.xml的项目UPDATE_KEY
        /// </summary>
        public string LimitKey { get; private set; }
        /// <summary>
        /// 当前站点是否禁用升级
        /// </summary>
        /// <returns></returns>
        public bool CurrPointWasLimited()
        {
            //服务端没限制
            if (string.IsNullOrEmpty(this.LimitKey))
            {
                return false;
            }
            string[] arr = this.LimitKey.Split(new char[] {',',':',';' }, 
                StringSplitOptions.RemoveEmptyEntries);
            string currKey = ShareMet.UpdateKey;
            return !arr.Contains(currKey, new StringCompareNoCase());
        }
        private ArrayList oldFileAl = new ArrayList();
        private ArrayList RenameFileLst = new ArrayList(); //需要改名的
        private string _ShortConfigName = "UpdateList.xml";
        public string ShortConfigName
        {
            get { return _ShortConfigName; }
            set { _ShortConfigName = value; }
        }
        public string AppDir = string.Empty;
        //private IntPtr handle;
        private Component component = new Component();
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);
        public string  FileRenameTo(string FileName )
        {
            RenameFile renFile = null;
            for (int i = 0; i < RenameFileLst.Count; i++)
            {
                renFile = ( (RenameFile)RenameFileLst[i] );
                if (renFile.OriFileName.Trim().ToUpper() == FileName.Trim().ToUpper())
                    return renFile.NewFileName;
            }
            return "";
        }
        public string UpdaterUrl
        {
            set { _updaterUrl = value; }
            get { return this._updaterUrl; }
        }
        public void WriteException(Exception ex)
        {
            BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message + ex.Source + ex.StackTrace);
        }
        public static bool DealUrlTruncFlag(ref string url)
        {
            if (url.EndsWith(";OK")) //不要使用这种
            {
                url = url.Replace(";OK", "");
                return true;
            }
            return false;
        }
        /// <summary>
        /// 返回下载文件的毫秒
        /// </summary>
        /// <param name="url"></param>
        /// <param name="tmpDir"></param>
        /// <returns></returns>
        private int GetUrlSpeed(string url, string tmpDir)
        {
            DealUrlTruncFlag(ref url);
            bool isFtp=url.StartsWith("ftp:", StringComparison.OrdinalIgnoreCase);
            if(isFtp ) return 1000000; //暂不从ftp下载
            if (!url.EndsWith(@"/")) url += @"/";
            url += "AlertInfo.xml";
            string dest = ShareMet.CombineDir(tmpDir, "AlertInfo.xml");
            if (ShareMet.FileExists(dest)) System.IO.File.Delete(dest);
            MyWebClient webclt = null;
            try
            {
                webclt = new MyWebClient(3000);
                ShareMet.CheckDownUrl(ref url, ref dest);
                webclt.UseDefaultCredentials = true;
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
    string.Format("Try to download '{0}' to '{1}'!", url, dest));
                DateTime start = DateTime.Now, end;
                webclt.DownloadFile(url, dest);
                end = DateTime.Now;
                if (ShareMet.FileExists(dest))
                {
                    TimeSpan st = new TimeSpan(start.Ticks);
                    TimeSpan et = new TimeSpan(end.Ticks);
                    return Math.Abs(et.Subtract(st).Duration().Milliseconds);
                }
                else
                {
                    throw new Exception(string.Format("Error occurs when downloading file from {0} !", url));
                }
            }
            finally
            {
                if (null != webclt) webclt.Dispose();
            }
        }
        private bool IsUrlOK(string url,string tmpDir)
        {
            if (!url.EndsWith(@"/")) url += @"/";
            url += "AlertInfo.xml";
            string dest = ShareMet.CombineDir(tmpDir, "AlertInfo.xml");
            if (ShareMet.FileExists(dest)) System.IO.File.Delete(dest);
            WebClient webclt = null;
            try
            {
                webclt = new WebClient();
                if (!url.StartsWith("ftp:", StringComparison.OrdinalIgnoreCase))
                {
                    webclt.UseDefaultCredentials = true;
                }
                ShareMet.CheckDownUrl(ref url, ref dest);
                webclt.DownloadFile(url, dest);
                return ShareMet.FileExists(dest);
            }
            catch(Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (null != webclt) webclt.Dispose();
            }
        }
        public string GetUpdateRootUrl(XmlFiles xmlobj)
        {
            string tmpDir = ShareMet.CombineDir(ShareMet.GetAppDir(), "temp");
            ShareMet.CheckFolderExists(tmpDir);
            string url = string.Empty;
            try
            {
                url = ShareMet.Config[CONFIG_KEY.FIXXED_UPDATE_URL];
                if (DealUrlTruncFlag(ref url)) return url;
                if (!string.Empty.Equals(url,
                        StringComparison.OrdinalIgnoreCase))
                {
                    if (IsUrlOK(url, tmpDir)) return url;
                }
                else
                    throw new Exception("Url is empty!");
            }
            catch(Exception ex)
            {
                WriteException(ex);
                try
                {
                    url = xmlobj.GetNodeValue("//RootUrl");
                    if (DealUrlTruncFlag(ref url)) return url;
                    if (!string.Empty.Equals(url,
                        StringComparison.OrdinalIgnoreCase))
                    {
                        if (IsUrlOK(url, tmpDir)) return url;
                    }
                    else
                        throw new Exception("Url is empty!");
                }
                catch(Exception ex1)
                {
                   WriteException(ex1);
                    try
                    {
                        url = xmlobj.GetNodeValue("//RootUrl1");
                        if (DealUrlTruncFlag(ref url)) return url;
                        if (!string.Empty.Equals(url,
                            StringComparison.OrdinalIgnoreCase))
                        {
                            if (IsUrlOK(url, tmpDir)) return url;
                        }
                        else
                            throw new Exception("Url is empty!");
                    }
                    catch (Exception ex2)
                    {
                        WriteException(ex2);
                        try
                        {
                            url = xmlobj.GetNodeValue("//RootUrl2");
                            if (DealUrlTruncFlag(ref url)) return url;
                            if (!string.Empty.Equals(url,
                                StringComparison.OrdinalIgnoreCase))
                            {
                                if (IsUrlOK(url, tmpDir)) return url;
                            }
                            else
                                throw new Exception("Url is empty when running update Agent!");
                        }
                        catch (Exception ex3)
                        {
                            WriteException(ex3);
                        }
                    }
                }
            }
             return string.Empty;
        }
        /// <summary>
        /// 根据测速结果取升级地址
        /// </summary>
        /// <param name="xmlobj"></param>
        /// <returns></returns>
        public string GetUpdateUrl(XmlFiles xmlobj)
        {
            List<UpdateUrlSpeed> urls = new List<UpdateUrlSpeed>();
            string tmpDir = ShareMet.CombineDir(ShareMet.GetAppDir(), "temp");
            ShareMet.CheckFolderExists(tmpDir);
            string url = string.Empty;
            int speed = 0;
            bool isDefault = false;
            try
            {
                url = xmlobj.GetNodeValue("//Url");
                isDefault = (DealUrlTruncFlag(ref url));
                if (!string.Empty.Equals(url,
                    StringComparison.OrdinalIgnoreCase))
                {
                    speed = GetUrlSpeed(url, tmpDir);
                    if (1000000 != speed)
                    {
                        urls.Add(new UpdateUrlSpeed(url, speed,isDefault));
                        BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO, string.Format("Url:'{0}' Speed:{1} ms!", url, speed));
                        if (isDefault) goto ExitAll;
                    }
                }
                else
                    throw new Exception("//Url is empty!");
            }
            catch (Exception ex)
            {
                speed = 10000000;
                WriteException(ex);
            }
            if (speed <= 200)
            {
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                    string.Format("Url: {0} speed:{1}ms,It is a well line,no testing other lines necessary!", url,speed));
            }
            else
            {
                try
                {
                    url = xmlobj.GetNodeValue("//Url1");
                    isDefault = (DealUrlTruncFlag(ref url)) ;
                    if (null == urls.FirstOrDefault(c =>
                        c.Url.Equals(url, StringComparison.OrdinalIgnoreCase)))
                    {
                        speed = 0;
                        if (!string.Empty.Equals(url,
                            StringComparison.OrdinalIgnoreCase))
                        {
                            speed = GetUrlSpeed(url, tmpDir);
                            if (1000000 != speed)
                            {
                                urls.Add(new UpdateUrlSpeed(url, speed,isDefault));
                                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO, string.Format("Url:'{0}' Speed:{1} ms!", url, speed));
                                if (isDefault) goto ExitAll;
                            }
                        }
                        else
                            throw new Exception("//Url1 is empty!");
                    }
                }
                catch (Exception ex)
                {
                    speed = 100000;
                    WriteException(ex);
                }
                if (speed <= 200)
                {
                    BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                        string.Format("Url: {0},speed: {1}ms,It is a well line,no testing other lines necessary!", url,speed));
                }
                else
                {
                    try
                    {
                        url = xmlobj.GetNodeValue("//Url2");
                        isDefault = (DealUrlTruncFlag(ref url)) ;
                        if (null == urls.FirstOrDefault(c =>
                            c.Url.Equals(url, StringComparison.OrdinalIgnoreCase)))
                        {
                            speed = 0;
                            if (!string.Empty.Equals(url,
                                StringComparison.OrdinalIgnoreCase))
                            {
                                speed = GetUrlSpeed(url, tmpDir);
                                if (1000000 != speed)
                                {
                                    urls.Add(new UpdateUrlSpeed(url, speed,isDefault));
                                    BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO, string.Format("Url:'{0}' Speed:{1} ms!", url, speed));
                                    if (isDefault) goto ExitAll;
                                }
                            }
                            else
                                throw new Exception("//Url2 is empty!");
                        }
                    }
                    catch (Exception ex)
                    {
                        speed = 1000000;
                        WriteException(ex);
                    }
                }
            }
            ExitAll:
            urls.Sort(delegate(UpdateUrlSpeed a, UpdateUrlSpeed b)
            {
                return a.TestMSecond.CompareTo(b.TestMSecond);
            });
            if (0 < urls.Count)
            {
                UpdateUrlSpeed defSite = urls.FirstOrDefault(c => c.IsDefault);
                if (null != defSite)
                {
                    url = defSite.Url;
                }
                else
                {
                    url = urls[0].Url;
                }
                DealUrlTruncFlag(ref url);
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                    string.Format("Choose the highest speed line :'{0}'!", url));
            }
            else
            {
#if USE_DEFAULT_URL_WHEN_NULL
                url = "http://your_default_update_point/vf/";
#else
                url = "";
#endif
            }
            //获取LimitKey
            try
            {
                FillLimitKey(tmpDir);
            }
            catch (Exception ex)
            {
                WriteException(ex);
            }
            return url;
        }
        public void FillLimitKey(string tmpdir)
        {
            string alertInfo = Path.Combine(tmpdir, "AlertInfo.xml");
            if (!File.Exists(alertInfo)) return;
            this.LimitKey = XPathGet.GetValue(alertInfo, "//Config//LimitKey");
        }
        public AppUpdater()
        {
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    component.Dispose();
                }
            }
            disposed = true;
        }
        ~AppUpdater()
        {
            Dispose(false);
        }
        ///旧文件是否存在
        private bool ExistsFile(string FileName)
        {
            int Count = oldFileAl.Count;
            for (int i = 0; i < Count; i++)
            {
                if (((LocalFileVersion)oldFileAl[i]).FileName.ToString().Trim().Equals(
                    FileName.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }
        private string GetOldFileVersion(string FileName)
        {
            int Count = oldFileAl.Count;
            for (int i = 0; i < Count; i++)
            {
                if (((LocalFileVersion)oldFileAl[i]).FileName.ToString().Trim().Equals(
                    FileName.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    return ((LocalFileVersion)oldFileAl[i]).Version;
                }
            }
            return "0.0.0.0";
        }
        private bool ServerFileIsNewer(string FileName, string Version)
        {
            if (!(ExistsFile(FileName))) return true;
            string oldVersion = GetOldFileVersion(FileName);
            //return ( string.Compare(Version ,oldVersion ,true )!=0 );
            bool ret= ServerFileIsNewerPri(Version, oldVersion);
            if (ret)
            {
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                   string.Format("File '{0}'  server:{1},client:{2}",
                   FileName, Version, oldVersion));
            }
            return ret;
        }
        //private static readonly char[] spt=new char[] { '.' };
        // x.x.x.x
        private bool ServerFileIsNewerPri(string svr, string local)
        {
            string svrNum = svr.Replace(".", "");
            string localNum = local.Replace(".", "");
            int ret_svr = 0, ret_local = 0;
            if (!int.TryParse(svrNum, out ret_svr)) ret_svr = 1;
            if (!int.TryParse(localNum, out ret_local)) ret_local = 0;
            return (ret_svr > ret_local);
        }
        public bool ServerConfigIsNewer()
        {
            if ("" == _clientFilePath || "" == _svrFilePath) return false;
            XmlFiles _svrObj = null, _cltObj = null;
            try
            {
                _svrObj = new XmlFiles(_svrFilePath);
                _cltObj = new XmlFiles(_clientFilePath);
                string svrVersion = _svrObj.GetNodeValue("//Version");
                string cltVersion = _cltObj.GetNodeValue("//Version");
                return (string.Compare(svrVersion, cltVersion, true) != 0);
            }
            catch
            {
                return false;
            }
            finally
            {
                if (null != _svrObj) _svrObj = null;
                if (null != _cltObj) _cltObj = null;
            }
        }
        /// 检查更新文件
        public int CheckForUpdate(string serverXmlFile, string localXmlFile, out Hashtable updateFileList)
        {
            _svrFilePath = serverXmlFile;
            _clientFilePath = localXmlFile;
            XmlFiles serverXmlFiles = null, localXmlFiles = null;
            int k = 0;      
            updateFileList = new Hashtable();
            try
            {

                if (!File.Exists(localXmlFile) || !File.Exists(serverXmlFile)) return -1;
                serverXmlFiles = new XmlFiles(serverXmlFile);
                localXmlFiles = new XmlFiles(localXmlFile);
                XmlNodeList newNodeList = serverXmlFiles.GetNodeList(@"AutoUpdater/Files");
                XmlNodeList oldNodeList = localXmlFiles.GetNodeList(@"AutoUpdater/Files");
                string newFileName, newVer, newKeyUpt, renTo, oldFileName, oldVer, tmpFileName;
                for (int j = 0; j < oldNodeList.Count; j++)
                {
                    try
                    {
                        if (oldNodeList.Item(j).Attributes == null) continue;
                        if (oldNodeList.Item(j).Attributes.Count < 3) continue;
                        oldFileName = oldNodeList.Item(j).Attributes["Name"].Value.Trim();
                        tmpFileName = oldFileName.ToUpper().Trim();
                        if (ShareMet.FileIsFixedExcepted(tmpFileName)) continue;
                        //排除文件
                        //if (oldFileName.Equals("abc.dll", StringComparison.OrdinalIgnoreCase)) continue;
                        if (clsExcept.Instance.FileWasExcepted(oldFileName))
                        {
                            BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                                string.Format("File '{0}' is exceptted!", oldFileName));
                            continue;//排除的文件
                        }
                        oldVer = oldNodeList.Item(j).Attributes["Ver"].Value.Trim();
                        oldFileAl.Add(new LocalFileVersion(oldFileName, oldVer));
                    }
                    catch (Exception ex)
                    {
                        BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message);
                    }
                }
                for (int i = 0; i < newNodeList.Count; i++)
                {
                    if (newNodeList.Item(i).Attributes == null) continue;
                    if (newNodeList.Item(i).Attributes.Count < 3) continue;
                    string[] fileList = new string[4];
                    newFileName = newNodeList.Item(i).Attributes["Name"].Value.Trim();
                    tmpFileName = newFileName.ToUpper().Trim();
                    if (ShareMet.FileIsFixedExcepted(tmpFileName)) continue;
                    //排除文件
                    //if (newFileName.Equals("abc.dll", StringComparison.OrdinalIgnoreCase)) continue;
                    if (clsExcept.Instance.FileWasExcepted(newFileName))
                    {
                        BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                            string.Format("File '{0}' is exceptted!", newFileName));
                        continue;//排除的文件
                    }
                    newVer = newNodeList.Item(i).Attributes["Ver"].Value.Trim();
                    newKeyUpt = "0";
                    renTo = ""; //重命名为
                    try
                    {
                        newKeyUpt = newNodeList.Item(i).Attributes["IsKeyUpt"].Value.Trim(); //是否关键更新
                    }
                    catch (Exception ex)
                    {
                        newKeyUpt = "0";
                        BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.WARN, ex.Message);
                    }
                    try
                    {
                        renTo = newNodeList.Item(i).Attributes["RenameTo"].Value.Trim();
                    }
                    catch
                    {
                        renTo = "";
                    }
                    if (ServerFileIsNewer(newFileName, newVer))
                    {
                        fileList[0] = newFileName;
                        fileList[1] = newVer;
                        fileList[2] = "";
                        fileList[3] = (newKeyUpt == "1" ? "Y" : "");
                        updateFileList.Add(k, fileList);
                        if (renTo != "") RenameFileLst.Add(new RenameFile(newFileName, renTo));
                        k++;
                        /*
                        BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.INFO,
                            "File " + newFileName + " on server is newer!");
                        */
                    }
                }
            }
            catch (Exception ex)
            {
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message);
                throw ex;
            }
            finally
            {
                if (null != serverXmlFiles) serverXmlFiles = null;
                if (null != localXmlFiles) localXmlFiles = null;
            }
            return k;
        }
        //检查当前版本
        public string GetVersion()
        {
            string localXmlFile = AppDir    + this.ShortConfigName ;
            XmlFiles XmlFile = new XmlFiles(localXmlFile);
            try
            {
                string Version = (XmlFile.GetNodeValue("//Version"));
                string VersionSort = (XmlFile.GetNodeValue("//VersionSort"));
                return (VersionSort + " " + Version);
            }
            catch(Exception ex)
            {
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message);
                return "";
            }
        }
        public bool NeedUpdate
        {
            get
            {
                string localXmlFile = AppDir  + this.ShortConfigName;
                XmlFiles XmlFile = new XmlFiles(localXmlFile);
                try
                {
                    string Value = XmlFile.GetNodeValue("//NeedUpdate");
                    return (Value.Trim().ToUpper() == "YES");
                }
                catch(Exception ex)
                {
                    BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message);
                    return false;
                }
            }
        }
        /// 返回下载更新文件的临时目录
        public void DownAutoUpdateFile(string downpath)
        {
            if (!System.IO.Directory.Exists(downpath))
                System.IO.Directory.CreateDirectory(downpath);
            string serverXmlFile =ShareMet.CombineDir(downpath , this.ShortConfigName );
            try
            {
                WebClient wClient = null;
                try
                {
                    wClient = new WebClient();
                    if (!this.UpdaterUrl.StartsWith("ftp:", StringComparison.OrdinalIgnoreCase))
                    {
                        wClient.UseDefaultCredentials = true;
                    }
                    string url = this.UpdaterUrl;
                    ShareMet.CheckDownUrl(ref url, ref serverXmlFile);
                    wClient.DownloadFile(url, serverXmlFile);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (null != wClient) wClient.Dispose();
                }
            }
            catch(Exception ex)
            {
                BIN.AutoUpdateLog.LogObj.AddLog(LOG_MODE.ERROR, ex.Message);
                throw new Exception("error occurs when getting the config file from server(connection timeout)!");
            }
        }
    }
}
